package protocol;

import com.google.common.collect.Lists;
import utils.NumberUtils;
import utils.StringUtils;

import java.util.List;
import java.util.Objects;

/**
 * set key1 value1
 * 参数的总个数，参数的字节长度、参数数据
 * 则这条命令对应的 RESP 协议报文内容为
 * *3CRLF$3CRLFsetCRLF$4CRLFkey1CRLF$6CRLFvalue1
 * 为了方便我们人类查看，我将 CRLF 控制字符打印出来
 * *3
 * $3
 * set
 * $4
 * key1
 * $6
 * value1
 * **/
public class RespParser {

    public Request parse(String request) {
        Request req;
        String[] arguments;
        boolean parsed = false;

        //maybe inline command
        if (!request.startsWith(ProtocolConstant.LIST_PREFIX)) {
            arguments = request.split(StringUtils.SPACE);
            parsed = true;
        }else{
            //把*清除掉
            request = request.substring(1);
            String[] cmds = request.split(StringUtils.CLRF);
            String sizeStr = cmds[0].trim();
            //参数数量
            Integer cmdSize = NumberUtils.parseInt(sizeStr);
            if(Objects.isNull(cmdSize)){
                Response errResp = ErrorResponse.errorSyntax();
                return Request.badRequest(errResp);
            }

            if (cmdSize * 2 + 1 != cmds.length || cmds.length < 3) {
                Response errResp = ErrorResponse.errorSyntax();
                return Request.badRequest(errResp);
            }

            //存放参数数组
            arguments = new String[cmdSize];
            int idx = 0;
            for(int i = 2;i < cmds.length;i++){
                arguments[idx++] = cmds[i];
            }
        }
        int len = arguments.length;
        if (len < 1) {
            Response errResp = ErrorResponse.errorSyntax();
            return Request.badRequest(errResp);
        }
        String command = arguments[0].toUpperCase();
        List<String> args = Lists.newArrayList(arguments);
        args.remove(0);
        req = new Request(command, args);
        if (!parsed) {
            request = parseRequest(arguments);
        }
        //设置字符串格式的命令行
        req.setRequest(request);
        return req;
    }

    /**
     * eg *3\r\n$3\r\nset\r\n$4\r\nname\r\n$3\r\nbob\r\n
     */
    public String parseRequest(String[] arguments) {
        StringBuilder request = new StringBuilder(ProtocolConstant.LIST_PREFIX);
        for (int i = 0; i < arguments.length; i ++) {
            String arg = arguments[i];
            request.append(arg);
            if (i != arguments.length - 1) {
                request.append(StringUtils.SPACE);
            }
        }
        return request.toString();
    }
}
